package com.mail.anteater.hibernate;

import java.net.URL;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.mail.anteater.util.ThreadQueue;

/**
 * @author Hwa This class garanties that only one single SessionFactory is
 *         instanciated and that the configuration is done thread safe as
 *         singleton. Actually it only wraps the Hibernate SessionFactory. You
 *         are free to use any kind of JTA or Thread transactionFactories.
 */
public class SessionFactoryUtil{

	final static Logger logger = Logger.getLogger(SessionFactoryUtil.class);
	
	private static ThreadQueue queue = new ThreadQueue();
	/** The single instance of hibernate SessionFactory */
	private static org.hibernate.SessionFactory mailSessionFactory;

	public SessionFactoryUtil() {
		logger.info("Hibernate server started.");
	}

	static {
		// Annotation and XML
		// sessionFactory = new
		// AnnotationConfiguration().configure().buildSessionFactory();
		// XML only
		
		URL url = SessionFactoryUtil.class.getResource("hibernate.cfg.xml");
		Configuration configuration2 = (new Configuration()).configure(url);
		mailSessionFactory = configuration2.buildSessionFactory();
		//mailSessionFactory = (SessionFactory) ctx.lookup("db88:/hibernate/SessionFactory");
	}

	public static SessionFactory getInstance() throws ClassNotFoundException {
		return mailSessionFactory;
	}

	/**
	 * Opens a session and will not bind it to a session context
	 * 
	 * @return the session
	 */
	public Session openSession() {
		return mailSessionFactory.openSession();
	}

	/**
	 * Returns a session from the session context. If there is no session in the
	 * context it opens a session, stores it in the context and returns it. This
	 * factory is intended to be used with a hibernate.cfg.xml including the
	 * following property <property
	 * name="current_session_context_class">thread</property> This would return
	 * the current open session or if this does not exist, will create a new
	 * session
	 * 
	 * @return the session
	 */
	public static Session getCurrentSession() {
		queue.enqueue(Thread.currentThread());
		return mailSessionFactory.getCurrentSession();
	}

	/**
	 * closes the session factory
	 */
	public static void close() {
		if (mailSessionFactory != null)
			mailSessionFactory.close();
		mailSessionFactory = null;

	}

	public static void endTransaction(){
		queue.complete();
	}

	//public 
}